package com.mx.api;

import com.mx.common.MD5Tool;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

@Api("文件上传")
@Controller
public class UploadController {
    private static final Logger logger = LoggerFactory.getLogger(UploadController.class);

    @Value("${upload.src:images}")
    private String rootPath;

    /**
     * 图片上传
     **/
    @ApiOperation("图片上传,支持png/jpg/gif/bmp")
    @PostMapping(value="/imageUpload",consumes = "multipart/*",headers = "content-type=multipart/form-data")
    @ResponseBody
    public Object imageUpload(@ApiParam(value = "上传图片",required = true) MultipartFile file) {
        Map<String,String> res = new HashMap<>();
        if (file.isEmpty()) {
            res.put("msg","文件为空");
            return res;
        }

        String fileName = file.getOriginalFilename();
        String suffix = getSuffix(fileName);
        if(!isImage(suffix)) {
            res.put("msg","不支持的文件类型或文件类型不明");
            return res;
        }

        try {
            byte[] data = file.getBytes();
            String md5 = MD5Tool.generateMD5ForByte(data);
            File parent = new File(rootPath,String.valueOf(md5.charAt(0)));
            if(!parent.exists()) parent.mkdirs();

            File dest = new File(parent, md5 + '.' + suffix);

            res.put("md5",md5);
            res.put("fileName",fileName);

            if(!dest.exists()) {
                try (OutputStream out = new FileOutputStream(dest)){
                    out.write(file.getBytes());
                    out.flush();
                }

                res.put("msg","上传成功");
            }else {
                res.put("msg","快速上传成功");
            }


        } catch (IOException e) {
            res.put("msg","i/o 异常");
        }

        return res;
    }

    private static String getSuffix(String fileName) {
        int index = fileName.lastIndexOf(".");

        String suffix = "";
        if(-1 != index){
            suffix = fileName.substring(index + 1);
        }
        return suffix;
    }

    private static boolean isImage(String suffix){
        return suffix.matches("^png|jpg|jpeg|gif|bmp$");
    }

    /**
     * 图片下载
     **/
    @GetMapping(value="/image/{md5}.{suffix}")
    @ApiOperation("图片文件下载")
    public void imageDownload(
            @PathVariable @ApiParam(value = "md5摘要",required = true) String md5,
            @PathVariable @ApiParam(value = "后缀",required = true) String suffix,
            HttpServletResponse response) throws IOException {
        File parent = new File(rootPath,String.valueOf(md5.charAt(0)));

        try(InputStream in = new FileInputStream(new File(parent,md5 + "." + suffix))) {
            byte[] temp = new byte[in.available()];
            in.read(temp);

            response.setContentType("image/" + suffix);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(temp);
            outputStream.flush();
        } catch (IOException e) {
            throw e;
        }
    }

    //通用文件上传

    @ApiOperation("文件上传")
    @PostMapping(value="/upload",consumes = "multipart/*",headers = "content-type=multipart/form-data")
    @ResponseBody
    public Object upload(@ApiParam(value = "上传文件",required = true) MultipartFile file) {
        Map<String,String> res = new HashMap<>();
        if (file.isEmpty()) {
            res.put("msg","文件为空");
            return res;
        }

        String fileName = file.getOriginalFilename();

        try {
            byte[] data = file.getBytes();
            String md5 = MD5Tool.generateMD5ForByte(data);
            File parent = new File(rootPath,String.valueOf(md5.charAt(0)));
            if(!parent.exists()) parent.mkdirs();

            File dest = new File(parent, md5);

            res.put("md5",md5);
            res.put("fileName",fileName);

            if(!dest.exists()) {
                try (OutputStream out = new FileOutputStream(dest)){
                    out.write(file.getBytes());
                    out.flush();
                }

                res.put("msg","上传成功");
            }else {
                res.put("msg","快速上传成功");
            }


        } catch (IOException e) {
            res.put("msg","i/o 异常");
        }

        return res;
    }

    @GetMapping(value="/file/{md5}/{fileName}")
    @ApiOperation("文件下载")
    public void download(
            @PathVariable @ApiParam(value = "md5摘要",required = true) String md5,
            @PathVariable @ApiParam(value = "下载显示的文件名",required = true) String fileName,
            HttpServletResponse response) throws IOException {
        File parent = new File(rootPath,String.valueOf(md5.charAt(0)));

        try(InputStream in = new FileInputStream(new File(parent,md5))) {
            byte[] temp = new byte[in.available()];
            in.read(temp);

            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment;fileName="+fileName);
            response.setContentLength(temp.length);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(temp);
            outputStream.flush();
        } catch (IOException e) {
            throw e;
        }
    }
}

